import { CloseCircleOutlined } from '@ant-design/icons';
import {
  FooterToolbar,
  PageContainer,
  ProForm,
  ProFormSelect,
  ProFormText,
  ProFormTextArea
} from '@ant-design/pro-components';
import { Button, Card, Col, Form, FormInstance, message, Popover, Row } from 'antd';
import type { FC } from 'react';
import { useState } from 'react';
import { getApi, saveUiCasePage, updateUiCasePage } from './service';
import useStyles from './style.style';
import { pageModule } from '../../api-module/service';
import { history, useModel, useRequest, useSearchParams } from '@umijs/max';
import { getEnvPage } from '@/pages/common-menu/environment/service';
import BaseURL from '@/components/BaseURL';
import { setKey } from '@/utils';
import RequestForm from '@/components/RequestForm';

type InternalNamePath = (string | number)[];

interface ErrorField {
  name: InternalNamePath;
  errors: string[];
}

interface ApiFormProps {
  [key: string]: any
  form?: FormInstance
}

const ApiForm: FC<ApiFormProps> = ({
  tabList = [
    { label: '请求头', key: 'header' },
    { label: '请求体', key: 'body' },
    { label: '查询参数', key: 'query' },
  ],
  children,
  onTabChange,
  form: parentForm,
}) => {
  const { styles } = useStyles();
  const [searchParams, setSearchParams] = useSearchParams()
  const id = searchParams.get('id')
  const [form] = Form.useForm(parentForm)
  const [error, setError] = useState<ErrorField[]>([]);
  const { initialState } = useModel('@@initialState');
  const [currentEdit, setCurrentEdit] = useState('header')

  const getErrorInfo = (errors: ErrorField[]) => {
    const errorCount = errors.filter((item) => item.errors.length > 0).length;
    if (!errors || errorCount === 0) {
      return null;
    }
    const scrollToField = (fieldKey: string) => {
      const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
      if (labelNode) {
        labelNode.scrollIntoView(true);
      }
    };
    const errorList = errors.map((err) => {
      if (!err || err.errors.length === 0) {
        return null;
      }
      const key = err.name[0] as 'name' | 'url' | 'owner' | 'approver' | 'dateRange' | 'type';
      return (
        <li key={key} className={styles.errorListItem} onClick={() => scrollToField(key)}>
          <CloseCircleOutlined className={styles.errorIcon} />
          {/* <div className={styles.errorMessage}>{err.errors[0]}</div>
          <div className={styles.errorField}>{fieldLabels[key]}</div> */}
        </li>
      );
    });
    return (
      <span className={styles.errorIcon}>
        <Popover
          title="表单校验信息"
          content={errorList}
          overlayClassName={styles.errorPopover}
          trigger="click"
          getPopupContainer={(trigger: HTMLElement) => {
            if (trigger && trigger.parentNode) {
              return trigger.parentNode as HTMLElement;
            }
            return trigger;
          }}
        >
          <CloseCircleOutlined />
        </Popover>
        {errorCount}
      </span>
    );
  };

  const onFinish = async (values: Record<string, any>) => {
    const hide = message.loading('正在保存');

    try {
      const api = id ? updateUiCasePage : saveUiCasePage

      let body = ''
      if (values?.bodyType != 'NONE') {
        body = JSON.stringify(values?.[values?.bodyType])
      }
      const res = await api({
        ...values,
        id: id,
        projectId: initialState?.currentProject?.id,
        header: JSON.stringify(values?.header),
        body,
        query: JSON.stringify(values?.query),
      });
      hide();
      if (res?.code == 0) {
        message.success('保存成功');
        if (res?.data?.id) {
          setSearchParams({
            id: res?.data?.id
          })
        }
        refresh()
        return true;
      }
      return false
    } catch (error) {
      hide();
      message.error('保存失败请重试！');
      return false;
    }
  };

  const onFinishFailed = (errorInfo: any) => {
    setError(errorInfo.errorFields);
  };


  const { refresh } = useRequest(() => {
    return getApi({ id, projectId: initialState?.currentProject?.id })
  }, {
    refreshDeps: [id], ready: !!id && !children, onSuccess(data) {
      const newValues = {
        ...data,
      }
      try {
        if (newValues.header) {
          newValues.header = setKey(JSON.parse(newValues.header), 'id')
        }
        if (newValues.body) {
          const body = JSON.parse(newValues.body)
          newValues[newValues.bodyType] = setKey(body, 'id')
          newValues.body = setKey(body, 'id')
        }
        if (newValues.query) {
          newValues.query = setKey(JSON.parse(newValues.query), 'id')
        }
      } catch (e) {
        console.log(e);
      }
      form.setFieldsValue(newValues)
    }
  })

  const main = <>
    <Card title="接口信息" className={styles.card} bordered={false}>
      <Row gutter={16}>
        <Col lg={6} md={12} sm={24}>
          <ProFormText
            label={'接口名称'}
            name="name"
            rules={[
              {
                required: true,
                message: '请输入接口名称',
              },
            ]}
            placeholder="请输入接口名称"
          />
        </Col>
        <Col lg={6} md={12} sm={24}>
          <ProFormSelect
            label={'请求方式'}
            name="method"
            rules={[
              {
                required: true,
                message: '请选择请求方式',
              },
            ]}
            options={[
              {
                label: 'GET',
                value: 'GET'
              },
              {
                label: 'POST',
                value: 'POST'
              },
              {
                label: 'PUT',
                value: 'PUT'
              },
              {
                label: 'DELETE',
                value: 'DELETE'
              },
              {
                label: 'HEAD',
                value: 'HEAD'
              },
              {
                label: 'OPTIONS',
                value: 'OPTIONS'
              },
            ]}
            placeholder="请选择请求方式"
          />
        </Col>
        {!children && <Col lg={6} md={12} sm={24}>
          <ProFormSelect
            label={'所属模块'}
            name="moduleId"
            rules={[
              {
                required: true,
                message: '请选择模块',
              },
            ]}

            request={async () => {
              const res = await pageModule({ current: 1, pageSize: 100 })

              return res?.data?.currentData?.map((item: any) => ({
                label: item?.name,
                value: item?.id,
              })) || []
            }}
            placeholder="请选择模块"
          />
        </Col>}
        <Col lg={6} md={12} sm={24}>
          <ProFormSelect
            label={'所属环境'}
            name="environmentId"
            rules={[
              {
                required: true,
                message: '请选择所属环境',
              },
            ]}
            request={async () => {
              const res = await getEnvPage({ current: 1, pageSize: 100 })

              return res?.data?.currentData?.map((item: any) => ({
                label: item?.name,
                value: item?.id,
              }))
            }}
            placeholder="请选择所属环境"
          />
        </Col>
        <Col lg={24} md={24} sm={24}
        >
          <Form.Item noStyle shouldUpdate={(pre, next) => pre?.environmentId != next?.environmentId}>
            {(form) => <ProFormText
              label={'接口地址'}
              name="path"
              fieldProps={{
                addonBefore: <BaseURL id={form.getFieldValue('environmentId')} />
              }}
              rules={[
                {
                  required: true,
                  message: '请输入接口地址',
                },
              ]}
              placeholder="请输入接口地址"
            />}
          </Form.Item>
        </Col>
        {!children && <Col lg={6} md={12} sm={24}>
          <ProFormSelect
            label={'接口等级'}
            name="level"
            rules={[
              {
                required: true,
                message: '请选择接口等级',
              },
            ]}
            options={[
              {
                label: 'P0',
                value: 'p0',
              },
              {
                label: 'P1',
                value: 'p1',
              },
              {
                label: 'P2',
                value: 'p2',
              },
              {
                label: 'P3',
                value: 'p3',
              },
            ]}
            placeholder="请选择接口等级"
          />
        </Col>}

        <Col lg={24} md={24} sm={24}
        >
          <ProFormTextArea
            label={'接口描述'}
            name="description"
            placeholder="请输入接口描述"
          />
        </Col>
      </Row>
    </Card>
    <Card
      bordered={false}
      tabList={tabList}
      activeTabKey={currentEdit}
      onTabChange={(val: any) => {
        onTabChange?.(val)
        setCurrentEdit(val)
      }}
    >
      <RequestForm form={form} currentEdit={currentEdit}>
        {children}
      </RequestForm>
    </Card>
  </>

  if (children) return main

  return (
    <PageContainer>
      <ProForm
        layout="vertical"
        requiredMark
        submitter={{
          render: (props, dom) => {
            return (
              <FooterToolbar>
                {getErrorInfo(error)}
                <Button onClick={() => {
                  history.push('/api-auto/api')
                }}>返回</Button>
                {dom}
              </FooterToolbar>
            );
          },
        }}
        form={form}
        initialValues={{
        }}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
      >
        {main}
      </ProForm>
    </PageContainer>
  );
};
export default ApiForm;
